/**
 * Validates that a URL is safe for redirection.
 * Only allows HTTP and HTTPS protocols to prevent XSS attacks.
 *
 * @param url - The URL string to validate
 * @throws Error if the URL has an unsafe protocol
 */
export function validateRedirectUrl(url: string): void {
  try {
    const parsedUrl = new URL(url)
    if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:')
      throw new Error('Authorization URL must be HTTP or HTTPS')
  }
  catch (error) {
    if (
      error instanceof Error
      && error.message === 'Authorization URL must be HTTP or HTTPS'
    )
      throw error
    // If URL parsing fails, it's also invalid
    throw new Error(`Invalid URL: ${url}`)
  }
}

/**
 * Check if URL is a private/local network address or cloud debug URL
 * @param url - The URL string to check
 * @returns true if the URL is a private/local address or cloud debug URL
 */
export function isPrivateOrLocalAddress(url: string): boolean {
  try {
    const urlObj = new URL(url)
    const hostname = urlObj.hostname.toLowerCase()

    // Check for localhost
    if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1')
      return true

    // Check for private IP ranges
    const ipv4Regex = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
    const ipv4Match = hostname.match(ipv4Regex)
    if (ipv4Match) {
      const [, a, b] = ipv4Match.map(Number)
      // 10.0.0.0/8
      if (a === 10)
        return true
      // 172.16.0.0/12
      if (a === 172 && b >= 16 && b <= 31)
        return true
      // 192.168.0.0/16
      if (a === 192 && b === 168)
        return true
      // 169.254.0.0/16 (link-local)
      if (a === 169 && b === 254)
        return true
    }

    // Check for .local domains
    return hostname.endsWith('.local')
  }
  catch {
    return false
  }
}
